package edu.gmu.atelier;

/**
 * Solves for x* for the equation Ax=b where Ax*=b* is the "closest"
 * to b in the span(A) (||b - Ax*|| &lt= ||b - Ax|| for all x in R^N).
 * <p>
 * The point Ax*=b* in span(A) is always closest to b however, if A has
 * dependent vectors there WILL be many x* that produce b*, x* will
 * not be unique.
 * <p>
 * The solver uses the normal equation A^T A x* = A^T b and solves for
 * x* = (A^T A)^-1 A^T b  using LUFactor.
 * <p>
 * @TODO Need to not use LUFactor because it requires A be invertible, when 
 * we can find a solution by using 0 for the free variables and providing
 * a valid solution.
 * 
 * @author James H. Pope
 */
public class LSGeneralSolver implements Solver
{
    private Matrix a    = null;
    
    private Matrix ata   = null;
    private Matrix at    = null;
    private LUFactor luf = null;
    
    public LSGeneralSolver( Matrix a )
    {
        this.a = a;
        
        // Decompose - remember matrices/vectors needed for solving
        this.at  = a.transpose();
        this.ata = at.mult(a);
        this.luf = new LUFactor(ata);
    }
    
    public Matrix getA()
    {
        return this.a;
    }
    
    public Matrix getAT()
    {
        return this.at;
    }
    
    public Matrix getATA()
    {
        return this.ata;
    }
    
    //------------------------------------------------------------------------//
    // Interface methods
    //------------------------------------------------------------------------//
    public Vector solve( Vector b )
    {
        Vector atb   = b.mult(at);
        Vector xstar = luf.solve(atb);
        return xstar;
    }
    
}
